package com.zjsru.leetcode75.level1;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @Author: cookLee
 * @Date: 2023-10-03
 * 反转字符串中的单词
 */
public class ReverseWords {

    /**
     * 主
     * 输入：s = "the sky is blue"
     * 输出："blue is sky the"
     * \
     * 输入：s = "  hello world  "
     * 输出："world hello"
     * 解释：反转后的字符串中不能存在前导空格和尾随空格。
     * \
     * 输入：s = "a good   example"
     * 输出："example good a"
     * 解释：如果两个单词间有多余的空格，反转后的字符串需要将单词间的空格减少到仅有一个。
     *
     * @param args args
     */
    public static void main(String[] args) {
        ReverseWords reverseWords = new ReverseWords();
        String s= "the sky is    blue";
        System.out.println(reverseWords.reverseWords2(s));
    }

    /**
     * 反向词:模拟
     *
     * @param s s
     * @return {@link String}
     */
    public String reverseWords(String s) {
        String trim = s.trim();
        List<String> wordList = Arrays.asList(trim.split("\\s+"));
        Collections.reverse(wordList);
        return String.join(" ", wordList);
    }

    /**
     * 反向单词:自定义方法实现
     *
     * @param s s
     * @return {@link String}
     */
    public String reverseWords2(String s) {
        StringBuilder sb = this.trimSpaces(s);

        // 翻转字符串
        this.reverse(sb, 0, sb.length() - 1);

        // 翻转每个单词
        this.reverseEachWord(sb);

        return sb.toString();
    }

    /**
     * 删除多余的空格
     *
     * @param s s
     * @return {@link StringBuilder}
     */
    public StringBuilder trimSpaces(String s) {
        int left = 0, right = s.length() - 1;
        // 去掉字符串开头的空白字符
        while (left <= right && s.charAt(left) == ' ') {
            ++left;
        }

        // 去掉字符串末尾的空白字符
        while (left <= right && s.charAt(right) == ' ') {
            --right;
        }

        // 将字符串间多余的空白字符去除
        StringBuilder sb = new StringBuilder();
        while (left <= right) {
            char c = s.charAt(left);
            if (c != ' ') {
                sb.append(c);
            } else if (sb.charAt(sb.length() - 1) != ' ') {
                //此刻只记录一个空格
                sb.append(c);
            }
            ++left;
        }
        return sb;
    }

    /**
     * 反向 反转出来后是 eulb si yks eht 每个单词都反转的情况
     *
     * @param sb    某人
     * @param left  左
     * @param right 右侧
     */
    public void reverse(StringBuilder sb, int left, int right) {
        while (left < right) {
            char tmp = sb.charAt(left);
            sb.setCharAt(left++, sb.charAt(right));
            sb.setCharAt(right--, tmp);
        }
    }

    /**
     * 反转每个单词
     *
     * @param sb 某人
     */
    public void reverseEachWord(StringBuilder sb) {
        int n = sb.length();
        int start = 0, end = 0;

        while (start < n) {
            // 循环至单词的末尾
            while (end < n && sb.charAt(end) != ' ') {
                ++end;
            }
            // 翻转单词
            this.reverse(sb, start, end - 1);
            // 更新start，去找下一个单词
            start = end + 1;
            ++end;
        }
    }

}
